﻿package baidu.reader.txt.model
{
    import baidu.lib.serialization.*;
    import baidu.reader.common.*;
    import baidu.reader.common.model.*;
    import baidu.ui.managers.*;
    import flash.events.*;
    import flash.utils.*;

    public class TxtDataModel extends EventDispatcher implements IPageProvider
    {
        private var dataProxy:TxtRemoteDataProxy;
        private var _current_docid:String;
        private var _default_rn:int = 50;
        private var _totalPage:int;
        private var _pageFirstCharArray:Array;
        private var _textArray:Array;
        private var _currentBlock:int;
        private var _blockCacheStart:int = -100;
        private var _blockCacheEnd:int = -100;
        private var _currentTextData:String;
        private var _cumulativeTextData:String = "";
        private var _isLoading:Boolean = false;
        private var _pageStartArrays:Array;

        public function TxtDataModel(param1:IEventDispatcher = null)
        {
            this._pageFirstCharArray = [NaN, 0];
            this._textArray = [];
            this._pageStartArrays = [];
            super(param1);
            this.init();
            return;
        }// end function

        private function init() : void
        {
            this.dataProxy = new TxtRemoteDataProxy();
            this.dataProxy.addEventListener(Event.COMPLETE, this.dataCompleteHandler);
            this.dataProxy.addEventListener(ErrorEvent.ERROR, this.dataErrorHandler);
            var _loc_1:* = InstanceManager.createSingletonInstance(AppConfigModel);
            this._default_rn = _loc_1.default_rn;
            return;
        }// end function

        private function dataErrorHandler(event:Event) : void
        {
            this._isLoading = false;
            dispatchEvent(new ErrorEvent(ErrorEvent.ERROR));
            return;
        }// end function

        private function dataCompleteHandler(event:Event) : void
        {
            var docInfo:Object;
            var tmpBinaryData:ByteArray;
            var contentStr:String;
            var event:* = event;
            this._currentTextData = "";
            this._textArray = [];
            var rawByteArray:* = this.dataProxy.data;
            rawByteArray.endian = Endian.LITTLE_ENDIAN;
            var docInfoBinaryData:* = new ByteArray();
            docInfoBinaryData.endian = Endian.LITTLE_ENDIAN;
            rawByteArray.position = 0;
            if (rawByteArray.bytesAvailable > 106 + rawByteArray.position)
            {
                rawByteArray.readBytes(docInfoBinaryData, 0, 106);
            }
            else
            {
                trace("binaryData.bytesAvailable: " + rawByteArray.bytesAvailable);
                trace("数据格式错误，文件太小");
                this._isLoading = false;
                dispatchEvent(new Event(ErrorEvent.ERROR));
                return;
            }
            var docInfoStr:* = docInfoBinaryData.readMultiByte(docInfoBinaryData.bytesAvailable, "utf-8");
            try
            {
                docInfo = JSON.decode(docInfoStr);
            }
            catch (e:Error)
            {
                trace("解析文档信息失败");
            }
            this._totalPage = int(docInfo["totalPage"]);
            var si:* = rawByteArray.position;
            this._pageFirstCharArray = [NaN, 0];
            var i:* = (si + 1);
            var iLen:* = rawByteArray.length;
            while (i < iLen)
            {
                
                if (rawByteArray[i] == 0)
                {
                    tmpBinaryData = new ByteArray();
                    tmpBinaryData.endian = Endian.LITTLE_ENDIAN;
                    rawByteArray.position = si;
                    rawByteArray.readBytes(tmpBinaryData, 0, i - si);
                    si = si + (i - si);
                    rawByteArray.position = si + 1;
                    tmpBinaryData.position = 0;
                    while (tmpBinaryData[tmpBinaryData.position] == 0 && tmpBinaryData.bytesAvailable)
                    {
                        
                        var _loc_3:* = tmpBinaryData;
                        var _loc_4:* = tmpBinaryData.position + 1;
                        _loc_3.position = _loc_4;
                    }
                    contentStr = tmpBinaryData.readMultiByte(tmpBinaryData.bytesAvailable, "utf-8");
                    contentStr = contentStr.replace(/\r""\r/g, "");
                    this._pageFirstCharArray.push(this._pageFirstCharArray[(this._pageFirstCharArray.length - 1)] + contentStr.length);
                    this._textArray.push(contentStr);
                }
                i = (i + 1);
            }
            this.updatePageStartArrays();
            this._currentTextData = this._textArray.join("");
            if (this._currentBlock == (this._blockCacheStart - 1))
            {
                this._blockCacheStart = this._currentBlock;
                dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.TOP));
            }
            else if (this._currentBlock == (this._blockCacheEnd + 1))
            {
                this._blockCacheEnd = this._currentBlock;
                dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.BOTTOM));
            }
            else
            {
                this._blockCacheEnd = this._currentBlock;
                this._blockCacheStart = this._currentBlock;
                dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.REPLACE));
            }
            this._isLoading = false;
            dispatchEvent(event);
            return;
        }// end function

        public function loadNextBlock() : void
        {
            this.loadBlock(this._current_docid, (this._blockCacheEnd + 1));
            return;
        }// end function

        public function loadPreviousBlock() : void
        {
            if (this._blockCacheStart <= 0)
            {
                dispatchEvent(new Event(ErrorEvent.ERROR));
                return;
            }
            this.loadBlock(this._current_docid, (this._blockCacheStart - 1));
            return;
        }// end function

        public function loadBlock(param1:String, param2:int) : void
        {
            if (!this._isLoading)
            {
                if (param2 <= this._blockCacheEnd && param2 >= this.blockCacheStart && param1 == this.currentDocid)
                {
                    this._currentBlock = param2;
                    dispatchEvent(new ReaderEvent(ReaderEvent.TEXT_ADD, TxtChapterModel.NO_ACTION));
                    this._isLoading = false;
                    dispatchEvent(new Event(Event.COMPLETE));
                    return;
                }
                if (this._blockCacheStart - param2 > 1 || param2 - this._blockCacheEnd > 1 || param1 != this.currentDocid)
                {
                    this.reset();
                }
                this.dataProxy.load(param1, param2, this._default_rn);
                this._isLoading = true;
                this._currentBlock = param2;
                this._current_docid = param1;
            }
            return;
        }// end function

        public function loadPage(param1:String, param2:int) : void
        {
            var _loc_3:int = 0;
            while (param2 > (_loc_3 + 1) * this._default_rn)
            {
                
                _loc_3++;
            }
            if (param1 != this._current_docid)
            {
                this.reset();
                this.loadBlock(param1, _loc_3);
            }
            else
            {
                this.loadBlock(param1, _loc_3);
            }
            return;
        }// end function

        private function updatePageStartArrays() : void
        {
            this._pageStartArrays[this._currentBlock] = this._pageFirstCharArray.concat();
            return;
        }// end function

        public function reset() : void
        {
            this._blockCacheStart = -100;
            this._blockCacheEnd = -100;
            this._pageStartArrays = [];
            return;
        }// end function

        public function get currentBlockTextData() : String
        {
            return this._currentTextData;
        }// end function

        public function get cumulativeTextData() : String
        {
            return this._cumulativeTextData;
        }// end function

        public function get totalPage() : int
        {
            return this._totalPage;
        }// end function

        public function get pageFirstCharArray() : Array
        {
            return this._pageFirstCharArray;
        }// end function

        public function get currentBlock() : int
        {
            return this._currentBlock;
        }// end function

        public function get default_rn() : int
        {
            return this._default_rn;
        }// end function

        public function get currentDocid() : String
        {
            return this._current_docid;
        }// end function

        public function get blockCacheStart() : int
        {
            return this._blockCacheStart;
        }// end function

        public function get blockCacheEnd() : int
        {
            return this._blockCacheEnd;
        }// end function

        public function get pageStartArrays() : Array
        {
            return this._pageStartArrays;
        }// end function

    }
}
